home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
NeXT Education Software Sampler 1992 Fall
/
NeXT Education Software Sampler 1992 Fall.iso
/
SoundAndMusic
/
cmix
/
Minc
/
trees.c
< prev
next >
Wrap
C/C++ Source or Header
|
1991-03-16
|
13KB
|
779 lines
/*
* intermediate representation
*/
#include "defs.h"
#include <stdio.h>
double *disp_args;
int arg_count;
double *arg_list_stack[MAXSTACK];
int arg_count_stack[MAXSTACK];
int stack_ptr;
double parse_dispatch();
char buf[500];
extern Tree tp1,tp2,tp3;
extern int i1,i2,i3;
extern double f1,f2,f3;
/*
* floating point comparisons:
* f1 < f2 ==> -1
* f1 = f2 ==> 0
* f1 > f2 ==> 1
*/
/* useless funtion */
foo(){};
foo2(){};
cmp (f1,f2)
double f1,f2;
{
foo();
if (fabs(f1-f2)< EPS){// printf("cmp=%g %g %g \n",f1,f2,fabs(f1-f2));
return (0);
}
if ((f1-f2) > EPS) { //printf("cmp > %g %g %g \n",f1,f2,fabs(f1-f2));
return (1);
}
if ((f2-f1) > EPS) {// printf("cmp <%g %g %g \n",f1,f2,fabs(f1-f2));
return (-1);
}
}
Tree node(op,kind)
int op;
int kind;
{
Tree tp1;
tp1 = (Tree) emalloc(sizeof(struct tree));
tp1->op = op;
tp1->kind = kind;
tp1->u.child[0] = NULL;
tp1->u.child[1] = NULL;
tp1->u.child[2] = NULL;
tp1->u.child[3] = NULL;
return tp1;
}
/*
Tree tproc(){};
*/
Tree tnoop()
{
Tree tp1;
foo();
tp1=node(FREE,TNOOP);
return (tp1);
}
Tree tseq(e1,e2)
Tree e1,e2;
{
Tree tp1;
foo();
tp1=node(FREE,SEQ);
tp1->u.child[0] = e1;
tp1->u.child[1] = e2;
return tp1;
}
Tree top(op,e1,e2)
Tree e1,e2;
int op;
{
Tree tp1;
foo();
tp1 =node (op,OP);
tp1->u.child[0] = e1;
tp1->u.child[1] = e2;
return tp1;
}
Tree tunop(op,e1)
Tree e1;
int op;
{
Tree tp1;
foo();
tp1 = node(op,UNOP);
tp1->u.child[0] = e1;
return tp1;
}
Tree tconvert(op,e1)
int op;
Tree e1;
{
Tree tp1;
foo();
tp1=node (op,CONVERT);
tp1->u.child[0] = e1;
return tp1;
}
/*
Tree tfetch(){};
*/
Tree tstore(e1,e2)
Tree e1,e2;
{
Tree tp1;
foo();
tp1 = node(FREE,STORE);
tp1->u.child[0] = e1;
tp1->u.child[1] = e2;
return tp1;
}
/*
Tree tmove(){};
*/
/* not used *********************
Tree teseq(stm,e1)
Tree stm,e1;
{
Tree tp1;
foo();
tp1 = node(FREE,ESEQ);
tp1->u.child[0] = stm;
tp1->u.child[1] = e1;
return tp1;
}
*/
/*
Tree tbool(){}
*/
/*
* converts symbol table entry into tree
* or initialize tree node to a symbol entry
*/
Tree tname(sym)
SYMBOL *sym;
{
Tree tp1;
foo();
tp1 = node(FREE,NAME);
tp1->u.sym = sym;
return tp1;
}
Tree tconst(ival)
int ival;
{
Tree tp1;
foo();
tp1 = node(FREE,CONST);
tp1->u.ival = ival;
return tp1;
}
Tree tconstf(fval)
double fval;
{
Tree tp1;
foo();
tp1 = node(FREE,CONSTF);
tp1->u.fval = fval;
return tp1;
}
/*
Tree falloc(){}
Tree ttemp(){}
*/
Tree tcall(e1,str)
Tree e1; /*arguments*/
char *str; /* name of function to call */
{
Tree tp1;
foo();
tp1 = node(FREE,CALL);
tp1->x.fctname = str;
tp1->u.child[0] = e1;
return tp1;
}
Tree tcand(test1,test2)
Tree test1,test2;
{
Tree tp1;
foo();
tp1 = node(FREE,CAND);
tp1->u.child[0] = test1;
tp1->u.child[1] = test2;
return tp1;
}
Tree tcor(test1,test2)
Tree test1,test2;
{
Tree tp1;
foo();
tp1 = node(FREE,COR);
tp1->u.child[0] = test1;
tp1->u.child[1] = test2;
return tp1;
}
Tree tnot(test1)
Tree test1;
{
Tree tp1;
foo();
tp1 = node(FREE,NOT);
tp1->u.child[0] = test1;
return tp1;
}
Tree trel(op,e1,e2)
int op;
Tree e1,e2;
{
Tree tp1;
foo();
tp1 = node (op,REL);
tp1->u.child[0] = e1;
tp1->u.child[1] = e2;
return tp1;
}
Tree targ(e1,args)
Tree e1,args;
{
Tree tp1;
foo();
tp1 = node(FREE,ARG);
tp1->u.child[0] = e1;
tp1->u.child[1] = args;
return tp1;
}
Tree tnoargs()
{
Tree tp1;
foo();
tp1 = node(FREE,NOARGS);
return tp1;
}
Tree tif(e1,e2)
Tree e1,e2;
{
Tree tp1;
foo();
tp1 = node (FREE,TIF);
tp1->u.child[0] = e1;
tp1->u.child[1] = e2;
return tp1;
}
Tree tifelse(e1,e2,e3)
Tree e1,e2,e3;
{
Tree tp1;
foo();
tp1 = node (FREE,TIFELSE);
tp1->u.child[0] = e1;
tp1->u.child[1] = e2;
tp1->u.child[2] = e3;
return tp1;
}
Tree tfor(e1,e2,e3,e4)
Tree e1,e2,e3,e4;
{
Tree tp1;
foo();
tp1 = node (FREE,TFOR);
tp1->u.child[0] = e1;
tp1->u.child[1] = e2;
tp1->u.child[2] = e3;
tp1->u.child[3] = e4;
return tp1;
}
Tree twhile(e1,e2)
Tree e1,e2;
{
Tree tp1;
foo();
tp1 = node (FREE,TWHILE);
tp1->u.child[0] = e1;
tp1->u.child[1] = e2;
return tp1;
}
/*
*
*
* This recursive function interprets the intermediate code
*
*/
Tree exct(tp)
Tree tp;
{
int i;
if (tp == NULL) return (NULL);
switch (tp->kind) {
case SEQ: {
exct(tp->u.child[0]);
exct(tp->u.child[1]);
break;
}
/* puts value and type into symbol pted to by child[0]u.sym */
case STORE: {
/* TBD: include handlng of different types */
tp->u.child[0]->u.sym->v.fval = exct(tp->u.child[1])->v.fval;
tp->u.child[0]->u.sym->type = tp->u.child[1]->type;
tp->v.fval = tp->u.child[0]->u.sym->v.fval;
tp->type = tp->u.child[1]->type;
break;
}
/* assign what's in the symobol into tree's value field */
case NAME: {
tp->type = tp->u.sym->type;
tp->v.fval = tp->u.sym->v.fval;
break;
}
case CONST: {
tp->type = T_INT;
tp->v.ival = tp->u.ival;
break;
}
case CONSTF: {
tp->type = T_FLOAT;
tp->v.fval = tp->u.fval;
break;
}
case ARG: {
exct(tp->u.child[0]);
if (arg_count ==MAXDISPARGS)
i_error("exeeded maximum number of arguments for a function call");
disp_args[arg_count++] = exct(tp->u.child[1])->v.fval;
break;
}
case NOARGS: { /* do nothing */
break;
}
case CALL: {
/* TBD: distinguish between internal or dispatcher function */
push_args ();
exct(tp->u.child[0]);
for (i=arg_count;i<MAXDISPARGS;i++) disp_args[i]=0;
tp->v.fval = parse_dispatch (tp->x.fctname,
disp_args,arg_count);
pop_args ();
tp->type = T_FLOAT;
break;
}
case NOT: {
tp->type = T_FLOAT;
if(cmp(0.0,exct(tp->u.child[0])->v.fval)==0)
tp->v.fval = 1.0;
else tp->v.fval = 0.0;
break;
}
case CAND: {
tp->type = T_FLOAT;
tp->v.fval = 0.0;
if(cmp(0.0,exct(tp->u.child[0])->v.fval)!= 0)
if(cmp(0.0,exct(tp->u.child[1])->v.fval)!= 0)
{ tp->type = T_FLOAT;
tp->v.fval = 1.0;
}
break;
}
case REL: {
tp->type = T_FLOAT;
switch((int)tp->op) {
case EQ: {
if(cmp(exct(tp->u.child[0])->v.fval,
exct(tp->u.child[1])->v.fval)== 0)
tp->v.fval = 1.0;
else
tp->v.fval = 0.0;
break;
}
case NEQ: {
if(cmp(exct(tp->u.child[0])->v.fval,
exct(tp->u.child[1])->v.fval)== 0)
tp->v.fval = 0.0;
else
tp->v.fval = 1.0;
break;
}
case LT: {
if(cmp(exct(tp->u.child[0])->v.fval,
exct(tp->u.child[1])->v.fval)== -1)
tp->v.fval = 1.0;
else
tp->v.fval = 0.0;
break;
}
case GT: {
if(cmp(exct(tp->u.child[0])->v.fval,
exct(tp->u.child[1])->v.fval)== 1)
tp->v.fval = 1.0;
else
tp->v.fval = 0.0;
break;
}
case LEQ: {
if(cmp(exct(tp->u.child[0])->v.fval,
exct(tp->u.child[1])->v.fval)<= 0)
tp->v.fval = 1.0;
else
tp->v.fval = 0.0;
break;
}
case GEQ: {
if(cmp(exct(tp->u.child[0])->v.fval,
exct(tp->u.child[1])->v.fval)>= 0)
tp->v.fval = 1.0;
else
tp->v.fval = 0.0;
break;
}
default: {
foo2();
sprintf(buf,"kind: %d; op: %d; u.fval: %f; v.fval: %f; type: %d",tp->kind,tp->op,tp->u.fval,tp->v.fval,tp->type);
msg(buf);
i_warning("tried to execute illegal REL in exct");
}
}
break; /* switch REL */
}
case OP:{
tp->type = T_FLOAT;
switch ((int)tp->op){
case PLUS: {
tp->v.fval=exct(tp->u.child[0])->v.fval +
exct(tp->u.child[1])->v.fval;
break;
}
case MINUS: {
tp->v.fval=exct(tp->u.child[0])->v.fval -
exct(tp->u.child[1])->v.fval;
break;
}
case MUL: {
tp->v.fval=exct(tp->u.child[0])->v.fval *
exct(tp->u.child[1])->v.fval;
break;
}
case DIV: {
tp->v.fval=exct(tp->u.child[0])->v.fval /
exct(tp->u.child[1])->v.fval;
break;
}
case POW: {
tp->v.fval=pow(exct(tp->u.child[0])->v.fval ,
exct(tp->u.child[1])->v.fval);
break;
}
default: {
foo2();
sprintf(buf,"kind: %d; op: %d; u.fval: %f; v.fval: %f; type: %d",tp->kind,tp->op,tp->u.fval,tp->v.fval,tp->type);
msg(buf);
i_warning("tried to execute illegal OP in exct");
}
}
break; /* switch OP */
}
case CONVERT: {
tp->type = T_FLOAT;
switch (tp->op) {
/****** TBD: THE CONVERSION FUNCTIONS NEED TO BE COMPLETED ******/
case CVTOC: { tp->v.fval=exct(tp->u.child[0])->v.fval;
break;
}
case CVTOL: { tp->v.fval=exct(tp->u.child[0])->v.fval;
break;
}
case CVTLO: { tp->v.fval=exct(tp->u.child[0])->v.fval;
break;
}
case CVTLC: { tp->v.fval=exct(tp->u.child[0])->v.fval;
break;
}
case CVTCL: { tp->v.fval=exct(tp->u.child[0])->v.fval;
break;
}
case CVTCO: { tp->v.fval=exct(tp->u.child[0])->v.fval;
break;
}
default: {
foo2();
sprintf(buf,"kind: %d; op: %d; u.fval: %f; v.fval: %f; type: %d",tp->kind,tp->op,tp->u.fval,tp->v.fval,tp->type);
msg(buf);
i_warning("tried to execute illegal CVT in exct");
}
}
break; /* switch CONVERT */
}
case UNOP: {
tp->type = T_FLOAT;
if (tp->op == NEG)
tp->v.fval= - exct(tp->u.child[0])->v.fval;
break;
}
case COR: {
tp->type = T_FLOAT;
tp->v.fval = 0;
if((cmp(0.0,exct(tp->u.child[0])->v.fval)!= 0) ||
(cmp(0.0,exct(tp->u.child[1])->v.fval)!= 0))
{ tp->v.fval = 1;
}
break;
}
case TIF: {
if (cmp(0.0,exct(tp->u.child[0])->v.fval)!= 0)
exct(tp->u.child[1]);
break;
}
case TIFELSE: {
if (cmp(0.0,exct(tp->u.child[0])->v.fval)!= 0)
exct(tp->u.child[1]);
else
exct(tp->u.child[2]);
break;
}
case TWHILE: {
while (cmp(0.0,exct(tp->u.child[0])->v.fval)!= 0)
exct(tp->u.child[1]);
break;
}
case TNOOP: {break;}
case TFOR: {
/*
for (exct(tp->u.child[0]);cmp(0.0,exct(tp->u.child[1])->v.fval)!= 0;
exct(tp->u.child[2]))
*/
exct(tp->u.child[0]);
while (cmp(0.0,exct(tp->u.child[1])->v.fval)!= 0) {
exct(tp->u.child[3]);
exct(tp->u.child[2]);
}
break;
}
default: {
foo2();
sprintf(buf,"kind: %d; op: %d; u.fval: %f; v.fval: %f; type: %d",tp->kind,tp->op,tp->u.fval,tp->v.fval,tp->type);
msg(buf);
i_warning("tried to execute illegal node in exct");
}
} /* switch kind */
return (tp);
}
/* keeps a stack of dispatch argument lists */
push_args ()
{
char *malloc();
if (stack_ptr >= MAXSTACK)
i_error ("stack overflow: too many nested function calls");
arg_list_stack[stack_ptr] = disp_args;
arg_count_stack[stack_ptr++] = arg_count;
disp_args = (double *) malloc (sizeof(double) * MAXDISPARGS);
arg_count = 0;
}
pop_args ()
{
free (disp_args);
if (stack_ptr == 0 )
i_error ("stack underflow");
disp_args = arg_list_stack[--stack_ptr];
arg_count = arg_count_stack[stack_ptr];
}
/*
*
*
* This recursive function frees space.
*
*/
free_tree(tp)
Tree tp;
{
if (tp == NULL) return (NULL);
switch (tp->kind) {
case SEQ: {
free_tree(tp->u.child[0]);
free_tree(tp->u.child[1]);
break;
}
case STORE: {
free_tree(tp->u.child[0]);
free_tree(tp->u.child[1]);
break;
}
case NAME: {
break;
}
case CONST: {
break;
}
case CONSTF: {
break;
}
case ARG: {
free_tree(tp->u.child[0]);
free_tree(tp->u.child[1]);
break;
}
case NOARGS: {
break;
}
case CALL: {
free_tree(tp->u.child[0]);
break;
}
case NOT: {
free_tree(tp->u.child[0]);
break;
}
case CAND: {
free_tree(tp->u.child[0]);
free_tree(tp->u.child[1]);
break;
}
case REL: {
free_tree(tp->u.child[0]);
free_tree(tp->u.child[1]);
break;
}
case OP:{
free_tree(tp->u.child[0]);
free_tree(tp->u.child[1]);
break;
}
case CONVERT: {
free_tree(tp->u.child[0]);
break;
}
case UNOP: {
free_tree(tp->u.child[0]);
break;
}
case COR: {
free_tree(tp->u.child[0]);
free_tree(tp->u.child[1]);
break;
}
case TIF: {
free_tree(tp->u.child[0]);
free_tree(tp->u.child[1]);
break;
}
case TIFELSE: {
free_tree(tp->u.child[0]);
free_tree(tp->u.child[1]);
free_tree(tp->u.child[2]);
break;
}
case TWHILE: {
free_tree(tp->u.child[0]);
free_tree(tp->u.child[1]);
break;
}
case TNOOP: {
break;
}
case TFOR: {
free_tree(tp->u.child[0]);
free_tree(tp->u.child[1]);
free_tree(tp->u.child[2]);
free_tree(tp->u.child[3]);
break;
}
} /* switch kind */
free(tp); /* actually free space */
}